﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASCalpuff.FileLayers
{
    /// <summary>
    /// 线源参数
    /// </summary>
    public class PG15:Group
    {

        // Number of buoyant line sources
        //with variable location and emission
        //parameters (NLN2)   

        //(If NLN2 > 0, ALL parameter data for
        //these sources are read from the file: LNEMARB.DAT)
        /// <summary>
        /// 可变源强浮力面源的数目,在lnemarb。Da
        /// </summary>
        int m_NLN2 = 0;

        public int NLN2
        {
            get { return m_NLN2; }
            set { m_NLN2 = value; }
        }

        //Number of buoyant line sources (NLINES)    
        /// <summary>
        /// 线源源的数目
        /// </summary>
        int m_NLINES = 0;

        public int NLINES
        {
            get { return m_NLINES; }
            set { m_NLINES = value; }
        }



        /// <summary>
        /// 排放单位
        ///1 =        g/s
        /// 2 =       kg/hr
        ///3 =       lb/hr
        ///4 =     tons/yr
        ///5 =     Odour Unit * m**3/s  (vol. flux of odour compound)
        /// 6 =     Odour Unit * m**3/min
        /// 7 =     metric tons/yr
        /// </summary>
        int m_ILNU = 1;

        public int ILNU
        {
            get { return m_ILNU; }
            set { m_ILNU = value; }
        }


        /// <summary>
        /// 15c中提供的具有可变排放速率换算因子的源物种的数量
        /// </summary>
        int m_NSLN1 = 0;

        public int NSLN1
        {
            get { return m_NSLN1; }
            set { m_NSLN1 = value; }
        }


        /// <summary>
        /// 每条线分成的线段的最大值（MSLUG=1）,代表每一条线的虚点的确切值（MSLUG=0）
        /// </summary>
        int m_MXNSEG = 7;

        public int MXNSEG
        {
            get { return m_MXNSEG; }
            set { m_MXNSEG = value; }
        }


        /// <summary>
        /// 计算过渡抬升处的距离的数量
        /// </summary>
        int m_NLRISE = 6;

        public int NLRISE
        {
            get { return m_NLRISE; }
            set { m_NLRISE = value; }
        }


        /// <summary>
        /// 平均建筑物长
        /// </summary>
        double m_XL = 1;

        public double XL
        {
            get { return m_XL; }
            set { m_XL = value; }
        }


        /// <summary>
        /// 平均建筑物高
        /// </summary>
        double m_HBL = 1;

        public double HBL
        {
            get { return m_HBL; }
            set { m_HBL = value; }
        }


        /// <summary>
        /// 平均建筑物宽
        /// </summary>
        double m_WBL = 1;

        public double WBL
        {
            get { return m_WBL; }
            set { m_WBL = value; }
        }
        //平均线源宽

        double m_WML = 1;

        public double WML
        {
            get { return m_WML; }
            set { m_WML = value; }
        }

        //建筑物之间的平均距离
        double m_DXL = 1;

        public double DXL
        {
            get { return m_DXL; }
            set { m_DXL = value; }
        }

        //平均浮力系数（M4/S）
        double m_FPRIMEL = 1;

        public double FPRIMEL
        {
            get { return m_FPRIMEL; }
            set { m_FPRIMEL = value; }
        }
        /// <summary>
        /// 线源参数
        /// </summary>
        List<LineSInfo> m_SInfo = new List<LineSInfo>();

        public List<LineSInfo> SInfo
        {
            get { return m_SInfo; }
            set
            {

                m_SInfo = value;


            }
        }


        //组C的变量

        //       Use this subgroup to describe temporal variations in the emission
        //rates given in 15b.  Factors entered multiply the rates in 15b.
        //Skip sources here that have constant emissions.

        //IVARY determines the type of variation, and is source-specific:
        //(IVARY)                                Default: 0
        //      0 =       Constant
        //      1 =       Diurnal cycle (24 scaling factors: hours 1-24)
        //      2 =       Monthly cycle (12 scaling factors: months 1-12)
        //      3 =       Hour & Season (4 groups of 24 hourly scaling factors,
        //                               where first group is DEC-JAN-FEB)
        //      4 =       Speed & Stab. (6 groups of 6 scaling factors, where
        //                               first group is Stability Class A,
        //                               and the speed classes have upper
        //                               bounds (m/s) defined in Group 12
        //      5 =       Temperature   (12 scaling factors, where temperature
        //                               classes have upper bounds (C) of:
        //                               0, 5, 10, 15, 20, 25, 30, 35, 40,
        //                               45, 50, 50+)
        /// <summary>
        ///源名称
        /// </summary>
        string m_SRCNAM = "";
        /// <summary>
        /// 源强变化因子标志
        /// 0=常数
        /// 1=日循环（24个因子）
        /// 3=小时和季节（4组，每组24个换算因子），春夏秋冬季节划分和中国一致
        /// 4=速度和稳定度（6组，每组6个换算因子）
        /// 5=温度（12个换算因子）
        /// </summary>
        int m_NARY = 0;
        /// <summary>
        /// 源强变化的速率和NARY要匹配
        /// </summary>
        List<double> m_QFAC = new List<double>();

        public List<double> QFAC
        {
            get { return m_QFAC; }
            set { m_QFAC = value; }
        }



    



        public override string WriteToGroup()
        {
            string Subgroup = "", TempStr;

            TempStr = StrWriter.GetCLine();
            TempStr += "INPUT GROUPS: 15a, 15b, 15c -- Line source parameters" + "\r\n";
            Subgroup += TempStr;

            TempStr = StrWriter.GetCLine();
            Subgroup += TempStr;

            TempStr = "! NLN2 = " + NLN2.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! NLINES = " + NLINES.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! ILNU = " + ILNU.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! NSLN1 = " + NSLN1.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! MXNSEG = " + MXNSEG.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! NLRISE = " + NLRISE.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! XL = " + XL.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! HBL = " + HBL.ToString() + " !" + "\r\n";
            Subgroup += TempStr;
            //
            TempStr = "! WBL = " + WBL.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! WML = " + WML.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            TempStr = "! DXL = " + DXL.ToString() + " !" + "\r\n";
            Subgroup += TempStr;
            TempStr = "! FPRIMEL = " + FPRIMEL.ToString() + " !" + "\r\n";
            Subgroup += TempStr;

            Subgroup += "!END!" + "\r\n";


            //进行排序
            List<string> arry = Sort.GetPollutantRightOrder();

            List<LineSInfo> arryLineSInfo = new List<LineSInfo>();
            arryLineSInfo.Clear();
            foreach (LineSInfo L in SInfo)
            {
                arryLineSInfo.Add((LineSInfo)L.Clone());
            }
            List<PolluteRatesVar> arryPolluteRatesVar = new List<PolluteRatesVar>();

            for (int i = 0; i < SInfo.Count; i++)
            {
                arryPolluteRatesVar.Clear();
                foreach (string a in arry)
                {
                    for (int j = 0; j < SInfo[i].X.ArryPolluteRatesVar.Count; j++)
                    {

                        if (a == SInfo[i].X.ArryPolluteRatesVar[j].PolluteName)
                        {
                            arryPolluteRatesVar.Add(SInfo[i].X.ArryPolluteRatesVar[j]);
                            break;
                        }
                    }
                }
                for (int k = 0; k < arryLineSInfo[i].X.ArryPolluteRatesVar.Count; k++)
                {
                    arryLineSInfo[i].X.ArryPolluteRatesVar[k] = (PolluteRatesVar)arryPolluteRatesVar[k].Clone();
                }
            }

            //---------------------------------------


            if (arryLineSInfo.Count > 0)
            {
                for (int i = 0; i < arryLineSInfo.Count; i++)
                {

                    TempStr = "! SRCNAM =  " + arryLineSInfo[i].SRCNAM + "  !" + "\r\n";
                    TempStr += "! X =        " + Math.Round(arryLineSInfo[i].X.BegX, 5).ToString() + ",        " + Math.Round(arryLineSInfo[i].X.BegY, 5).ToString() + ",        " + Math.Round(arryLineSInfo[i].X.EndX, 5).ToString() + ",        " + Math.Round(arryLineSInfo[i].X.EndY, 5).ToString() + ",        " + Math.Round(arryLineSInfo[i].X.ReleseHeight, 3).ToString() + ",        " + Math.Round(arryLineSInfo[i].X.Elevation, 3).ToString();
                    double A = 0;
                    for (int j = 0; j < arryLineSInfo[i].X.ArryPolluteRatesVar.Count; j++)
                    {
                        A = Math.Round(arryLineSInfo[i].X.ArryPolluteRatesVar[j].Rate * 1000 / 3600, 4);
                        if (arryLineSInfo[i].X.Unit == "g/s")
                        {
                            if (j % 3 == 0)
                            {
                                //每隔3行数据就换行
                                TempStr += ",  " + "\r\n" + arryLineSInfo[i].X.ArryPolluteRatesVar[j].Rate.ToString("E5");
                            }
                            else
                            {
                                TempStr += ",  " + arryLineSInfo[i].X.ArryPolluteRatesVar[j].Rate.ToString("E5");
                            }
                        }
                        else
                        {
                            if (j % 3 == 0)
                            {
                                TempStr += ",  " + "\r\n" + A.ToString("E5");
                            }
                            else
                            {
                                TempStr += ",  " + A.ToString("E5");
                            }
                        }
                    }

                    TempStr += "  !" + "\r\n" + "   ! END !" + "\r\n";
                    Subgroup += TempStr;
                }
            }

            string F = "";
            for (int i = 0; i < arryLineSInfo.Count; i++)
            {
                string D = "";
                for (int j = 0; j < arryLineSInfo[i].X.ArryPolluteRatesVar.Count; j++)
                {
                    if (arryLineSInfo[i].X.ArryPolluteRatesVar[j].IVARY != 0)
                    {
                        string A = "! SRCNAM = " + arryLineSInfo[i].SRCNAM + " !" + "\r\n";
                        string B = "! IVARY  =  " + arryLineSInfo[i].X.ArryPolluteRatesVar[j].IVARY + "  !" + "\r\n";
                        string C = "";
                        for (int k = 0; k < arryLineSInfo[i].X.ArryPolluteRatesVar[j].ArryCoefficient.Count; k++)
                        {
                            //C = "";
                            if (k != arryLineSInfo[i].X.ArryPolluteRatesVar[j].ArryCoefficient.Count - 1)
                            {
                                C = C + arryLineSInfo[i].X.ArryPolluteRatesVar[j].ArryCoefficient[k].ToString() + ",";
                            }
                            else
                            {
                                C = C + arryLineSInfo[i].X.ArryPolluteRatesVar[j].ArryCoefficient[k].ToString() + "      !";
                            }
                            if ((k + 1) % 6 == 0)
                            {
                                C = C + "\r\n";
                            }
                        }
                        C = "! " + arryLineSInfo[i].X.ArryPolluteRatesVar[j].PolluteName + "          = " + C + "!END!" + "\r\n";
                        D = D + A + B + C;
                    }
                }
                F = F + D;
            }
            Subgroup = Subgroup + F;

            return Subgroup;
        }

        public override void ReadFromGroup(Dictionary<string, string> dic)
        {
            foreach (KeyValuePair<string, string> m_dic in dic)
            {
                if (m_dic.Key == "NLN2")
                {
                    this.NLN2 = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "NLINES")
                {
                    this.NLINES = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "ILNU")
                {
                    this.ILNU = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "NSLN1")
                {
                    this.NSLN1 = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "MXNSEG")
                {
                    this.MXNSEG = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "NLRISE")
                {
                    this.NLRISE = Convert.ToInt32(m_dic.Value);
                }
                if (m_dic.Key == "XL")
                {
                    this.XL = Convert.ToDouble(m_dic.Value);
                }
                if (m_dic.Key == "HBL")
                {
                    this.HBL = Convert.ToDouble(m_dic.Value);
                }
                //
                if (m_dic.Key == "WBL")
                {
                    this.WBL = Convert.ToDouble(m_dic.Value);
                }
                if (m_dic.Key == "WML")
                {
                    this.WML = Convert.ToDouble(m_dic.Value);
                }
                if (m_dic.Key == "DXL")
                {
                    this.DXL = Convert.ToDouble(m_dic.Value);
                }
                if (m_dic.Key == "FPRIMEL")
                {
                    this.FPRIMEL = Convert.ToDouble(m_dic.Value);
                }

                LineSInfo ps = new LineSInfo();
                List<double> lst = new List<double>();

                if (m_dic.Key == "SRCNAM")
                {
                    ps.SRCNAM = m_dic.Value;
                }
                if (m_dic.Key == "X")
                {
                    lst = StrWriter.ReturnDouList(m_dic.Value);
                    ps.X.BegX = lst[0];
                    ps.X.BegY = lst[1];
                    ps.X.EndX = lst[2];

                    ps.X.EndY = lst[3];
                    ps.X.ReleseHeight = lst[4];
                    ps.X.Elevation = lst[5];


                    ps.X.ArryPolluteRatesVar.Clear();
                    for (int i = 6; i < lst.Count; i++)
                    {
                        PolluteRatesVar mPolluteRatesVar = new PolluteRatesVar();
                        mPolluteRatesVar.Rate = lst[i];
                        ps.X.ArryPolluteRatesVar.Add(mPolluteRatesVar);
                    }

                }
                SInfo.Add(ps);
            }
        }

    }



    /// <summary>
    /// 线源参数
    /// </summary>
    [Serializable]
    public class LineSInfo : ICloneable
    {
        /// <summary>
        /// 污染源编号
        /// </summary>
        string m_SRCNAM = "L";

        public string SRCNAM
        {
            get { return m_SRCNAM; }
            set { m_SRCNAM = value; }
        }

        private int m_Sid = 0;
        /// <summary>
        ///　污染源编号记录器，只增加，不减少以避免重复，且唯一.
        /// </summary>
        public int Sid
        {
            get { return m_Sid; }
            set { m_Sid = value; }
        }


        private string m_Name = "L";
        /// <summary>
        /// 污染源名称，非Inp文件
        /// </summary>
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }


        /// <summary>
        /// 线源位置信息
        /// </summary>
        LineXInfo m_X = new LineXInfo();

        public LineXInfo X
        {
            get { return m_X; }
            set { m_X = value; }
        }
        public object Clone()
        {

            LineSInfo obj = new LineSInfo();
            obj = (LineSInfo)this.MemberwiseClone();
            LineXInfo mLineXInfo = new LineXInfo();
            mLineXInfo = (LineXInfo)this.X.Clone();
            obj.X = mLineXInfo;

            return obj;
        }
    }
    /// <summary>
    /// 线源位置信息
    /// </summary>

    [Serializable]
    public class LineXInfo : ICloneable
    {
        /// <summary>
        /// 线源起始X坐标
        /// </summary>
        double m_BegX = 0;

        public double BegX
        {
            get { return m_BegX; }
            set { m_BegX = value; }
        }
        /// <summary>
        /// 线源起始Y坐标
        /// </summary>
        double m_BegY = 0;

        public double BegY
        {
            get { return m_BegY; }
            set { m_BegY = value; }
        }
        /// <summary>
        /// 线源结束X坐标
        /// </summary>
        double m_EndX = 0;

        public double EndX
        {
            get { return m_EndX; }
            set { m_EndX = value; }
        }
        /// <summary>
        /// 线源结束Y坐标
        /// </summary>
        double m_EndY = 0;

        public double EndY
        {
            get { return m_EndY; }
            set { m_EndY = value; }
        }

        /// <summary>
        /// 线源释放高度
        /// </summary>
        double m_ReleseHeight = 0;

        public double ReleseHeight
        {
            get { return m_ReleseHeight; }
            set { m_ReleseHeight = value; }
        }
        /// <summary>
        /// 基准海拔高度
        /// </summary>
        double m_Elevation = 0;

        public double Elevation
        {
            get { return m_Elevation; }
            set { m_Elevation = value; }
        }

        private string m_Unit = "g/s";//单位
        /// <summary>
        /// 单位
        /// </summary>
        public string Unit
        {
            get { return m_Unit; }
            set { m_Unit = value; }
        }

        private List<PolluteRatesVar> m_arryPolluteRatesVar = new List<PolluteRatesVar>();
        /// <summary>
        /// 污染物速率相关的一此参数
        /// </summary>
        public List<PolluteRatesVar> ArryPolluteRatesVar
        {
            get { return m_arryPolluteRatesVar; }
            set { m_arryPolluteRatesVar = value; }
        }


        public object Clone()
        {
            LineXInfo obj = new LineXInfo();
            obj = (LineXInfo)this.MemberwiseClone();

            List<PolluteRatesVar> arryPollu = new List<PolluteRatesVar>();
            for (int i = 0; i < this.ArryPolluteRatesVar.Count; i++)
            {
                arryPollu.Add((PolluteRatesVar)this.ArryPolluteRatesVar[i].Clone());
            }
            obj.ArryPolluteRatesVar = arryPollu;
            return obj;
        }
    }





}
